package com.hy.greedy;

public class SaleStock {


    /**
     * 714. 买卖股票的最佳时机含手续费
     * 力扣题目链接
     *
     * 给定一个整数数组 prices，其中第 i 个元素代表了第 i 天的股票价格 ；非负整数 fee 代表了交易股票的手续费用。
     *
     * 你可以无限次地完成交易，但是你每笔交易都需要付手续费。如果你已经购买了一个股票，在卖出它之前你就不能再继续购买股票了。
     *
     * 返回获得利润的最大值。
     *
     * 注意：这里的一笔交易指买入持有并卖出股票的整个过程，每笔交易你只需要为支付一次手续费。
     *
     * 示例 1: 输入: prices = [1, 3, 2, 8, 4, 9], fee = 2 输出: 8
     *
     * 解释: 能够达到的最大利润: 在此处买入 prices[0] = 1 在此处卖出 prices[3] = 8 在此处买入 prices[4] = 4 在此处卖出 prices[5] = 9 总利润: ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
     *
     * 思路
     * 贪心算法
     * 在贪心算法：122.买卖股票的最佳时机II中使用贪心策略不用关心具体什么时候买卖，只要收集每天的正利润，最后稳稳的就是最大利润了。
     *
     * 而本题有了手续费，就要关系什么时候买卖了，因为计算所获得利润，需要考虑买卖利润可能不足以手续费的情况。
     *
     * 如果使用贪心策略，就是最低值买，最高值（如果算上手续费还盈利）就卖。
     *
     * 此时无非就是要找到两个点，买入日期，和卖出日期。
     *
     * 买入日期：其实很好想，遇到更低点就记录一下。
     * 卖出日期：这个就不好算了，但也没有必要算出准确的卖出日期，只要当前价格大于（最低价格+手续费），就可以收获利润，至于准确的卖出日期，就是连续收获利润区间里的最后一天（并不需要计算是具体哪一天）。
     * 所以我们在做收获利润操作的时候其实有三种情况：
     *
     * 情况一：收获利润的这一天并不是收获利润区间里的最后一天（不是真正的卖出，相当于持有股票），所以后面要继续收获利润。
     * 情况二：前一天是收获利润区间里的最后一天（相当于真正的卖出了），今天要重新记录最小价格了。
     * 情况三：不作操作，保持原有状态（买入，卖出，不买不卖）
     *
     * @param price
     * @param fee
     * @return
     */

    public int maxProfit(int [] price,int fee){
        int buy = price[0] + fee;
        int sum = 0;
        for (int p : price) {
            // 当前价 + fee 与 买入价相比
            if (p + fee < buy){
                buy = p + fee;
            }else if (p > buy){
                // 卖出价  -  买入价
                sum += p - buy;
                buy = p;
            }
        }
        return sum;
    }

    public int saleStock(int [] price,int fee){
        int res = 0;
        int minPrice = price[0];
        for (int i = 0; i < price.length; i++) {
            if (price[i] < minPrice){
                minPrice = price[i];
            }
            // 情况三：保持原有状态（因为此时买则不便宜，卖则亏本）
            if (price[i] >= minPrice && price[i] <= minPrice + fee){
                continue;
            }
            if (price[i] >= minPrice){
                res += price[i] - minPrice - fee;
                minPrice = price[i] - fee;
            }
        }
        return res;
    }

    public static void main(String[] args) {
        SaleStock saleStock = new SaleStock();
        int [] price = {1, 3, 2, 8, 4, 9};
        int fee = 2;
        System.out.println("res: "+saleStock.saleStock(price,fee));
        System.out.println("res: "+saleStock.maxProfit(price,fee));
    }
}
